/***********************************************************************************
 * 文件名： mcu_pwm.h
 * 版本： 1
 * 说明：
 * 		SC8P1715 的PWM外设驱动。使用说明见头文件。在 sc8p1715_config.h 文件中可配置初始状态。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
***********************************************************************************/
#ifndef _MCU_PWM_H_
#define _MCU_PWM_H_

#include "mcu.h"

// 宏定义参数解析，用户一般无需关注

// 如果不需要高2位，定义 _HPwm_SetCH0H 为空，节省代码量
#if (PWM_CYCLE > 255)
#define _HPwm_SetCH0H(u16_v)            \
    {                                   \
        PWMD08 = ((u16_v) >> 8)&0x01;          \
        PWMD09 = ((u16_v) >> 9) & 0x01; \
    }
#else
#define _HPwm_SetCH0H(u16_v)
#endif

// 如果不需要高2位，定义 _HPwm_SetCH1H 为空，节省代码量
#if (PWM_CYCLE > 255)
#define _HPwm_SetCH1H(u16_v)            \
    {                                   \
        PWMD18 = ((u16_v) >> 8)&0x01;          \
        PWMD19 = ((u16_v) >> 9) & 0x01; \
    }
#else
#define _HPwm_SetCH1H(u16_v)
#endif

// 配置自动启停
#if (PWM_CH0_AUTO_ON_OFF)
#define _HPwm_CH0AutoONOFF(u16_v) \
    {                             \
        if ((u16_v) == 0)         \
            PWM0EN = 0;           \
        else                      \
            PWM0EN = 1;           \
    }
#else
#define _HPwm_CH0AutoONOFF(u16_v)
#endif
#if (PWM_CH1_AUTO_ON_OFF)
#define _HPwm_CH1AutoONOFF(u16_v) \
    {                             \
        if ((u16_v) == 0)         \
            PWM1EN = 0;           \
        else                      \
            PWM1EN = 1;           \
    }
#else
#define _HPwm_CH1AutoONOFF(u16_v)
#endif

// API

// PWM模块初始化
// 按照配置文件中的初始参数进行初始化。
// PWM管脚由烧录选项字节决定,将对应管脚设置成输出模式才能输出PWM波形。
// 注意中断初始状态在 Mcu_Init 中已统一初始化。
#if SC8P_MCU_TYPE == SC8P1715 || SC8P_MCU_TYPE == SC8P171xE
#define HPwm_Init()                                                                                                   \
    {                                                                                                                 \
        PWMCON = (PWM_CLKDIV << 5) | (PWM_CH1_DIR << 3) | (PWM_CH0_DIR << 2) | (PWM_CH1_EN << 1) | (PWM_CH0_EN << 0); \
        PWMTL = PWM_CYCLE;                                                                                            \
        PWMTH = PWM_CYCLE >> 8;                                                                                       \
        PWMD01H = (((PWM_CH1_DUTY & 0x0300) >> 8) << 2) | ((PWM_CH0_DUTY & 0x0300) >> 8);                             \
        PWMD0L = PWM_CH0_DUTY;                                                                                        \
        PWMD1L = PWM_CH1_DUTY;                                                                                        \
    }

#else
#define HPwm_Init()                                                                       \
    {                                                                                     \
        PWMCON0 = (PWM_CLKDIV << 5) | (PWM_CH1_EN << 1) | (PWM_CH0_EN << 0);              \
        PWMCON1 = (PWM_IO_SELECT << 6);                                                   \
        PWMCON2 = (PWM_CH1_DIR << 1) | (PWM_CH0_DIR << 0);                                \
        PWMTL = PWM_CYCLE;                                                                \
        PWMTH = PWM_CYCLE >> 8;                                                           \
        PWMD01H = (((PWM_CH1_DUTY & 0x0300) >> 8) << 4) | ((PWM_CH0_DUTY & 0x0300) >> 8); \
        PWMD0L = PWM_CH0_DUTY;                                                            \
        PWMD1L = PWM_CH1_DUTY;                                                            \
    }

#endif

// 获取PWM中断标志
// 在计数器清零（溢出，输出ON）时产生中断
#define HPwm_GetIntFlag() PWMIF

// 清除PWM中断标志
#define HPwm_ClrIntFlag() PWMIF = 0

// 立即停止 CH0 输出
// 管脚电平取决于IO输出寄存器
#define HPwm_CloseCH0() \
    {                   \
        PWM0EN = 0;     \
    }

// 开启 CH0 输出
#define HPwm_OpenCH0() \
    {                  \
        PWM0EN = 1;    \
    }

// 设置 CH0 的PWM值
// u16_v：PWM值，不能大于1023
#define HPwm_SetCH0(u16_v)           \
    {                                \
        _HPwm_SetCH0H(u16_v); \
        PWMD0L = u16_v;              \
        _HPwm_CH0AutoONOFF(u16_v);   \
    }

// 立即停止 CH1 输出
// 管脚电平取决于IO输出寄存器
#define HPwm_CloseCH1() \
    {                   \
        PWM1EN = 0;     \
    }

#define HPwm_OpenCH1() \
    {                  \
        PWM1EN = 1;    \
    }

#define HPwm_SetCH1(u16_v)           \
    {                                \
        _HPwm_SetCH1H(u16_v); \
        PWMD1L = u16_v;              \
        _HPwm_CH1AutoONOFF(u16_v);   \
    }

#endif
